package com.ys.day27.p7线程局部变量ThreadLocal;

import java.util.concurrent.ThreadLocalRandom;

/**
 * 描述:
 *ThreadLocal叫做线程线程局部变量，它跟synchronized是一对反义词，也就意味着每个线程都能够持有共享资源的副本。
 *
 * ​	synchronized：多个线程共享一个共享资源
 *
 * ​	ThreadLocal：每个线程都有自己独立的共享资源副本
 *
 * ​	ThreadLocal常用的方法：
 *
 * ​	initialValue() 设置共享资源初始化的值
 *
 * ​	**set(T) 用来将共享资源注入(设置)到ThreadLocal对象中**
 *
 * ​       **T get() 用来获取共享资源的对象**
 *
 * ​       remove() 删除ThreadLocal里面的共享资源对象
 * @author CodeYang
 * @version 2021/1/7 1:12
 */
public class ThreadLocal的了解与使用 {

    /**
     * 创建5个线程，观察每个线程是否有自己独立的共享资源
     * @param args
     */
    public static void main(String[] args) {

        for (int i = 0; i < 5; i++) {

            new Thread(new MyTask()).start();
        }

    }
}

class MyTask implements  Runnable{


    /**
     * 从StudentFactory里面获取共享资源，通过随机数为共享资源设置id
     * 打印结果如下：
     com.ys.day27.p7线程局部变量ThreadLocal.Student@36bdb2aa
     com.ys.day27.p7线程局部变量ThreadLocal.Student@36bdb2aa
     com.ys.day27.p7线程局部变量ThreadLocal.Student@36bdb2aa
     com.ys.day27.p7线程局部变量ThreadLocal.Student@12cddde4
     com.ys.day27.p7线程局部变量ThreadLocal.Student@12cddde4
     com.ys.day27.p7线程局部变量ThreadLocal.Student@12cddde4
     com.ys.day27.p7线程局部变量ThreadLocal.Student@1c3d736f
     com.ys.day27.p7线程局部变量ThreadLocal.Student@1c3d736f
     com.ys.day27.p7线程局部变量ThreadLocal.Student@1c3d736f
     com.ys.day27.p7线程局部变量ThreadLocal.Student@6eb7e2c8
     com.ys.day27.p7线程局部变量ThreadLocal.Student@6eb7e2c8
     com.ys.day27.p7线程局部变量ThreadLocal.Student@6eb7e2c8
     com.ys.day27.p7线程局部变量ThreadLocal.Student@35118e73
     com.ys.day27.p7线程局部变量ThreadLocal.Student@35118e73
     com.ys.day27.p7线程局部变量ThreadLocal.Student@35118e73

     5次线程 15 次输出,但是每三次都是操作的同一个对象,由此可以怎么 ThreadLocal 可以把变量锁在线程中使用
     * 由此可以证明每个线程都有自己独立的Student共享资源
     */
    @Override
    public void run() {
        // 获取共享资源
        ThreadLocalRandom random = ThreadLocalRandom.current();
        for (int i = 0; i < 3; i++) {
            Student student = StudentFactory.getCurrentStudent();
            student.setId(random.nextInt(500)+1);
            System.out.println(student);
        }
    }
}
